package com.appium.manager.template.aop;

import com.appium.manager.element.ElementHelper;
import lombok.extern.slf4j.Slf4j;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.io.*;
import java.nio.channels.FileChannel;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.UUID;


/**
 * <p>
 * 异常快照记录拦截器
 * </p>
 *
 * @author 大忽悠
 * @create 2022/7/15 22:11
 */
@Slf4j
public class ExSnapshotInterceptor implements MethodInterceptor {

    private final String snapshotFilePath;
    private final Boolean openExSnapshot;
    private final ElementHelper elementHelper;

    public ExSnapshotInterceptor(String snapshotFilePath, Boolean openExSnapshot, ElementHelper elementHelper) {
        this.snapshotFilePath = snapshotFilePath;
        this.openExSnapshot = openExSnapshot;
        this.elementHelper = elementHelper;
    }

    @Nullable
    @Override
    public Object invoke(@Nonnull MethodInvocation invocation) throws Throwable {
        Object res = null;
        try {
            res = invocation.proceed();
        } catch (Exception e) {
            if (openExSnapshot) {
                exSnapshot(e);
            }
            throw e;
        }
        return res;
    }

    public void exSnapshot(Exception e) {
        String exFileName = getExFileName();
        log.error("出现了异常,进行异常截图,得到的异常截图生成在: {} 路径下", exFileName);
        preCheck(snapshotFilePath);
        transferExInfoTo(e,exFileName+".txt");
        transferExSnapshotTo(exFileName+".png");
    }

    private void preCheck(String exFileName) {
        File file = new File(exFileName);
        if(!file.exists()){
            file.mkdirs();
        }
    }

    private String getExFileName() {
        String curTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yy-MM-dd-HH-mm-ss"));
        curTime += "-" + UUID.randomUUID().toString().substring(0, 5) ;
        return snapshotFilePath+curTime;
    }

    private void transferExInfoTo(Exception e,String exFile) {
        try (PrintStream print = new PrintStream(exFile)) {
             print.println(e);
        } catch (FileNotFoundException ex) {
            ex.printStackTrace();
        }
    }

    private void transferExSnapshotTo(String targetFilePath) {
        FileChannel sourceChannel = null;
        FileChannel targetChannel = null;
        try {
            File sourceFile = elementHelper.snapshot();
            sourceChannel = new FileInputStream(sourceFile).getChannel();
            targetChannel = new FileOutputStream(targetFilePath).getChannel();
            sourceChannel.transferTo(0, sourceFile.length(), targetChannel);
        } catch (IOException ex) {
            ex.printStackTrace();
        } finally {
            if (sourceChannel != null) {
                try {
                    sourceChannel.close();
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
            }
            if (targetChannel != null) {
                try {
                    targetChannel.close();
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
            }
        }
    }
}
